<template>
  <section class="mode-select">
    <button
      v-for="item in SCORE_CORRECT_TYPE"
      :key="item"
      :disabled="
        noPaper ||
        (item === SCORE_CORRECT_TYPE.CLICK && ANSWER_TYPE.TEXT === answerType)
      "
      @click="changeScoreMode(item)"
      :class="{ active: scoreMode == item }"
      class="btn"
    >
      {{ SCORE_CORRECT_TEXT[item] }}
    </button>
  </section>

  <section tabindex="-1" @keyup.enter="submitScore" v-if="showBoard">
    <ScorePointInput
      :mark-model="false"
      :topic-title="title"
      :show-board="showBoard"
      :score-mode="scoreMode"
      :full-score="totalScore"
      v-model:modelValue="clickScore"
      v-model:nowScore="nowScore"
    ></ScorePointInput>
  </section>
  <section class="submit-buttons">
    <button
      :disabled="noPaper || autoSubmitScore"
      @click="submitScore"
      class="btn-submit btn"
    >
      提交批改
    </button>
    <div>
      <button
        :disabled="noPaper"
        @click="giveFullScore"
        class="btn-score btn btn-full"
      >
        满分
      </button>
      <button
        :disabled="noPaper"
        @click="giveZeroScore"
        class="btn-score btn btn-zero"
      >
        零分
      </button>
    </div>
    <el-checkbox
      v-model="autoSubmitScore"
      :disabled="noPaper"
      style="margin-left: 10px"
      v-if="quickMode"
      >自动提交
    </el-checkbox>
  </section>

  <section class="num-pad" :class="{ 'small-key': !normalMode }">
    <div class="flex-row space-between">
      <template v-if="!normalMode">
        <span class="spn">打分步长</span>
        <el-select
          v-model="nowScoreStep"
          :disabled="noPaper"
          placeholder="请选择"
          class="step-select"
        >
          <el-option
            v-for="score in scoreSteps"
            :key="'o' + score"
            :label="score"
            :value="score"
          />
        </el-select>
      </template>
      <button
        class="reverse__btn btn"
        :class="{ 'reverse-active': isNumKeyReverse }"
        @click="isNumKeyReverse = !isNumKeyReverse"
        v-if="scoreMode === 3"
      >
        <i class="el-icon-sort"></i>
        分值倒序
      </button>
    </div>

    <div v-if="clickMode" class="flex-row">
      <el-radio-group
        v-model="isAddScore"
        :disabled="noPaper"
        @change="onChangeAddOrMinus()"
        class="add-or-minus"
      >
        <el-radio :value="true">加分</el-radio>
        <el-radio :value="false">减分</el-radio>
      </el-radio-group>
    </div>
    <!-- 系统分数键 -->
    <div
      v-for="(score, index) of systemNumKeys"
      :key="'sk' + index"
      :disabled="noPaper || score > nowScorePointFullScore"
      @click="setScore(score)"
      class="num-pad__button"
      :class="{ 'score-active': clickMode && nowClickScore === score }"
    >
      {{ numKeyPrefix + score }}
    </div>
    <!-- 功能键 -->
    <button
      :disabled="noPaper"
      v-if="clickMode"
      @click="undo()"
      class="num-pad__button btn"
    >
      撤销
    </button>
    <button
      :disabled="noPaper"
      v-if="normalMode"
      @click="onClickNormalDot5()"
      class="num-pad__button btn"
    >
      .5
    </button>
    <button
      :disabled="noPaper"
      @click="clearNowScore()"
      class="num-pad__button btn"
    >
      清空
    </button>
  </section>
  <p class="mode-tip">1. {{ modeTip }}</p>
  <p class="mode-tip">2. 鼠标长按右侧图标拖拽可移动打分板</p>
</template>

<script setup>
import { ref, watch, computed, onMounted, onBeforeMount } from 'vue'
import { scoreClickMitt } from '@/utils/tools/bus'
import { ElMessage } from 'element-plus'
import {
  SCORE_CORRECT_TEXT,
  SCORE_CORRECT_TYPE,
  ANSWER_TYPE
} from '@/views/assignment/single-correct/data'
import ScorePointInput from './ScorePointInput.vue'

const emits = defineEmits(['submitChange'])
const props = defineProps({
  // 是否等待批改 0已经批改，1未批改
  showBoard: { type: Boolean, default: true },
  // 标题
  title: { type: String, required: true },
  totalScore: { type: Number, required: true },
  answerType: { type: String }
})

const preScore = ref(-1)
const scoreMode = ref(SCORE_CORRECT_TYPE.QUICK)
const nowScoreStep = ref(1)
const isNumKeyReverse = ref(false) // 是否倒序
const isAddScore = ref(true) // 点击打分是加分还是减分
const nowClickScore = ref(-1) // 点击打分模式点一下给的分
const clickScore = ref() //当前点击打分总分数
const nowScore = ref(null) //目前的打分
const autoSubmitScore = ref(preScore.value === -1)
const scoreMarks = ref([]) //点击打分的坐标集

const noPaper = computed(() => {
  // 是否已评价完成
  return !props.showBoard
})

const quickMode = computed(() => {
  return scoreMode.value == SCORE_CORRECT_TYPE.QUICK
})
const normalMode = computed(() => {
  return scoreMode.value == SCORE_CORRECT_TYPE.NORMAL
})
const clickMode = computed(() => {
  return scoreMode.value == SCORE_CORRECT_TYPE.CLICK
})

// 总分数
const nowScorePointFullScore = computed(() => {
  return props.totalScore !== 0 ? props.totalScore : 0
})

// 更改打分模式
const changeScoreMode = mode => {
  scoreMode.value = mode
  if (!clickMode.value) {
    nowScore.value = null
    clickScore.value = undefined
  } else {
    clickScore.value = isAddScore.value ? 0 : nowScorePointFullScore.value
  }
  autoSubmitScore.value = quickMode.value && preScore.value < 0
  scoreClickMitt.emit('clear-marks')
}

// 打分步长列表
const stepList = computed(() => {
  if (noPaper.value) {
    return []
  }
  const length =
    Math.floor(nowScorePointFullScore.value / nowScoreStep.value) + 1
  const result = []
  for (let i = 0; i !== length; i++) {
    const value = i * nowScoreStep.value
    result.push(value)
  }
  if (nowScorePointFullScore.value % nowScoreStep.value) {
    result.push(nowScorePointFullScore.value)
  }
  return result
})

// 可切换的步长
const scoreSteps = computed(() => {
  return [0.5, 1, 1.5, 2, 3, 4, 5].filter(
    //---
    v => v < props.totalScore
  )
})

// 打分的键盘
const systemNumKeys = computed(() => {
  let list = []
  switch (scoreMode.value) {
    case 1:
      list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
      break
    case 2:
    case 3:
      list = JSON.parse(JSON.stringify(stepList.value))
      break
    default:
      list = []
  }
  if (scoreMode.value === 3 && isNumKeyReverse.value) {
    list.reverse()
  }
  return list
})

const onClickNormalDot5 = () => {
  if (!normalMode.value) {
    return
  }
  nowScore.value = nowScore.value ? nowScore.value + 0.5 : 0.5
}

const numKeyPrefix = computed(() => {
  if (!clickMode.value) {
    return ''
  }
  return isAddScore.value ? '+' : '-'
})

// 点击键盘上的进行设置分数
const setScore = score => {
  if (quickMode.value) {
    nowScore.value = score
    if (autoSubmitScore.value) submitScore()
    return
  }
  if (normalMode.value) {
    nowScore.value = Number((nowScore.value || '') + score.toString())
    return
  }

  if (clickMode.value) {
    nowClickScore.value = nowClickScore.value == score ? -1 : score
  }
}

// 回评价得手动提交
const giveFullScore = () => {
  nowScore.value = nowScorePointFullScore.value
  if (clickMode.value) {
    clickScore.value = nowScore.value
    scoreClickMitt.emit('clear-marks')
  }
  quickMode.value && autoSubmitScore.value && submitScore()
}

const giveZeroScore = () => {
  nowScore.value = 0
  if (clickMode.value) {
    clickScore.value = nowScore.value
    scoreClickMitt.emit('clear-marks')
  }
  quickMode.value &&
    autoSubmitScore.value &&
    preScore.value < 0 &&
    submitScore()
}

const modeTip = computed(() => {
  switch (scoreMode.value) {
    case SCORE_CORRECT_TYPE.QUICK:
      return preScore.value >= 0
        ? '回评状态下需手动提交成绩'
        : '选择自动提交分数后，无需手动提交成绩'
    case SCORE_CORRECT_TYPE.NORMAL:
      return '选择得分后需手动提交成绩'
    case SCORE_CORRECT_TYPE.CLICK:
      return '可在卷面上按题目得分点依次给分，\n需手动提交成绩'
    default:
      return ''
  }
})

const clearNowScore = () => {
  if (clickMode.value) {
    scoreClickMitt.emit('clear-marks')
  }
  clickScore.value = undefined
  nowScore.value = null
}

const validateScore = () => {
  if (
    nowScore.value < 0 ||
    nowScore.value > props.totalScore ||
    nowScore.value % 0.5
  ) {
    ElMessage.warning('分数超出给分范围')
    return false
  }
  return true
}

const submitScore = () => {
  if (clickScore.value !== undefined && clickMode.value) {
    nowScore.value = clickScore.value
  }
  if (nowScore.value === null) {
    ElMessage.error('请先给题目打分再提交！')
    return
  }
  if (!validateScore()) return
  if (clickMode.value) emits('submitChange', nowScore.value, scoreMarks.value)
  else emits('submitChange', nowScore.value)
}

const initData = score => {
  preScore.value = score
  nowScore.value = score !== -1 ? score : null
  nowClickScore.value = -1
  autoSubmitScore.value = score < 0
  scoreMarks.value.find(item => item.length)?.[0]?.score[0] == '-'
    ? (isAddScore.value = false)
    : (isAddScore.value = true)
  scoreMode.value =
    scoreMarks.value.some(item => item.length) &&
    props.answerType === ANSWER_TYPE.PIC
      ? ((clickScore.value = nowScore.value), SCORE_CORRECT_TYPE.CLICK)
      : SCORE_CORRECT_TYPE.QUICK
}

defineExpose({ initData })
watch(
  () => scoreMarks.value,
  val => {
    if (val.some(item => item.length)) {
      scoreMode.value = SCORE_CORRECT_TYPE.CLICK
      clickScore.value = nowScore.value
    }
  }
)

// 更改点击打分当前选择的总分数
const onChangeAddOrMinus = () => {
  clickScore.value = isAddScore.value ? 0 : nowScorePointFullScore.value
  scoreClickMitt.emit('clear-marks')
}

// 撤销操作
const undo = () => {
  scoreClickMitt.emit('undo')
}

onMounted(() => {
  // 监听打分点的坐标点是否发生变化
  scoreClickMitt.on('change-score-marks', data => {
    if (!data.isClick && clickMode.value && nowClickScore.value != -1) {
      scoreClickMitt.emit('is-click-score-mode', clickMode.value)
      scoreClickMitt.emit('change-click-value', {
        score: nowClickScore.value,
        prefix: numKeyPrefix.value
      })
    }

    scoreMarks.value = data.marks

    let sumOfScores = scoreMarks.value.reduce((a, b) => {
      console.log(1212, b)
      return (
        b.reduce((accumulator, currentObject) => {
          return accumulator + Number(currentObject.score)
        }, 0) + a
      )
    }, 0)
    const isMinus =
      scoreMarks.value.find(item => item.length)?.[0]?.score[0] == '-'
    if (data.updateScore && clickMode.value) {
      clickScore.value = !isMinus
        ? sumOfScores
        : nowScorePointFullScore.value + sumOfScores
    }
  })
})

onBeforeMount(() => {
  scoreClickMitt.off('change-score-marks')
})
watch(
  () => [nowClickScore.value, numKeyPrefix.value],
  ([score, prefix]) => {
    scoreClickMitt.emit('change-click-value', {
      score,
      prefix
    })
  }
)

watch(
  () => clickMode.value,
  val => {
    scoreClickMitt.emit('is-click-score-mode', val)
  }
)
</script>

<style lang="less" scoped>
@baseURL: '@/assets/images/single-correct';
button {
  border: 0;
  background-color: transparent;
  outline: 0;
  cursor: pointer;

  &:disabled {
    background-color: #e8e8e8 !important;
    color: #d9d9d9 !important;
    cursor: not-allowed;
  }

  &:focus,
  &:hover {
    filter: opacity(0.8);
  }

  &:active {
    filter: brightness(0.9);
  }
}

.mode-select {
  flex: 0 0 auto;
  margin-bottom: 16px;
  display: flex;
  justify-content: space-between;

  .btn {
    border-bottom: 6px solid transparent;
    padding: 17px 0 12px;
    font-size: 16px;
    font-weight: bold;
    color: #595959;

    &:disabled {
      background-color: transparent !important;
      color: #d9d9d9;
    }
  }

  .active {
    border-color: #009cff;
    color: #009cff;

    &:disabled {
      background-color: transparent;
      border-color: #d9d9d9;
      color: #d9d9d9;
    }
  }
}

.submit-buttons {
  flex: 0 0 auto;
  .btn-submit {
    margin-top: 16px;
    border-radius: 3px;
    width: 100%;
    height: 52px;
    background-color: #91d101;
    line-height: 50px;
    font-size: 22px;
    color: #fff;
  }

  .btn-score {
    margin: 13px 8px 13px 0;
    border-radius: 4px;
    width: 70px;
    height: 35px;
    line-height: 35px;
    font-size: 16px;
    color: #fff;
  }

  .btn-full {
    background-color: #3ecac9;
  }

  .btn-zero {
    background-color: #fd686d;
  }
}

.num-pad {
  max-height: 350px;
  flex: 0 1 auto;
  border: 1px solid #cfcfcf;
  box-sizing: border-box;
  padding: 4px 0 12px;
  border-radius: 4px;
  display: flex;
  flex-wrap: wrap;
  overflow-y: auto;
  .flex-row {
    padding: 5px 17px 0;
    box-sizing: border-box;
    width: 100%;
    display: flex;
    align-items: center;
    font-size: 16px;
    color: #595959;
    .spn {
      flex-shrink: 0;
    }
    .step-select {
      margin-left: 9px;
      width: 72px;
    }
  }
  .space-between {
    justify-content: space-between;
  }
  .reverse__btn {
    width: 80px;
    height: 40px;
    font-size: 14px;
    color: #595959;
    border: 1px solid #cfcfcf;
    border-radius: 4px;
    margin-left: 15px;
    .el-icon-sort {
      transform: rotate(90deg);
    }
  }
  .reverse-active {
    background-color: #ebf5ff;
    color: #009cff;
  }
  .score-active {
    background-color: #41bfff !important;
    color: #fff !important;
  }
  .num-pad__button {
    flex: 0 0 auto;
    margin: 12px 0 0 17px;
    border: 1px solid #cfcfcf;
    border-radius: 4px;
    box-sizing: border-box;
    width: 70px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    background-color: #fff;
    font-size: 20px;
    color: #595959;
    cursor: pointer;

    &:not(:disabled):hover {
      background-color: #f7f9fa;
      color: #595959;
    }

    &:active {
      background-color: #ebf5ff;
      color: #595959;
    }
  }

  .small-key {
    .num-pad__button {
      margin-left: 14px;
      width: 54px;
      height: 54px;
      font-size: 16px;
    }
  }
}

.mode-tip {
  flex: 0 0 auto;
  margin: 6px -5px 0px;
  text-align: left;
  white-space: pre;
  font-size: 16px;
  color: #8c8c8c;
}
</style>
